package com.touringapp.android.activity;

import java.util.ArrayList;

import org.json.JSONArray;
import org.json.JSONObject;

import com.touringapp.android.R;
import com.touringapp.android.utils.http.RequestUtility;

import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.AsyncTaskLoader;
import android.support.v4.content.DefaultAsyncTaskLoader;
import android.support.v4.content.Loader;


public class UserListActivity extends FragmentActivity implements LoaderManager.LoaderCallbacks<LoadUsersResult> {
    private boolean destroyed = false;
    protected BrowseCommentsState mState;
    private static final String KEY_STATE = "browseCommentsState";
    private ProgressDialog progressDialog;
    
    private static final int[] USER_ROW_VIEWS = new int[] {R.id.user_name};
    private static final String[] USER_ROW_COLUMNS = new String[] {
            UserAccessorMap.KEY_TITLE};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.users);
        if (savedInstanceState != null) {
            mState = (BrowseCommentsState) savedInstanceState
                    .getSerializable(KEY_STATE);
        } else {
            mState = new BrowseCommentsState();
        }
        Loader<LoadUsersResult> loader = getSupportLoaderManager().initLoader(0, null, this);
        if (loader.isStarted()) {
        	progressDialog = ProgressDialog.show(this, null, "Loading users...");        		
        } else {        
	        if (mState.dataList == null) {
	        	progressDialog = ProgressDialog.show(this, null, "Loading users...");
	        	loader.startLoading();
	        }
        }
        findViewById(R.id.refresh).setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				DefaultAsyncTaskLoader<LoadUsersResult> loader = (DefaultAsyncTaskLoader<LoadUsersResult>)getSupportLoaderManager().initLoader(0, null, UserListActivity.this);
				loader.cancelLoad();
				loader.reset();
				progressDialog = ProgressDialog.show(UserListActivity.this, null, "Loading users...");
				loader.startLoading();
			}
		});
        updateView(true);
    }
    
    @Override
    protected void onResume() {
        super.onResume();
    }

    private void updateView(boolean onActivityCreate) {
        final TextView noUsersMessageContainer = (TextView)findViewById(R.id.no_users_text_view);
    	ListView userListView = (ListView)findViewById(R.id.userList);
        final ArrayList<User> dataList = mState.dataList;
        if (dataList != null) {
        	//show list
        	if (dataList.isEmpty()){
            	noUsersMessageContainer.setVisibility(View.VISIBLE);
            	userListView.setVisibility(View.GONE);
        		noUsersMessageContainer.setText("No users yet");
        	} else {
	            SimpleAdapter listAdapter = new SimpleAdapter(
	                    this, UserAccessorMap.convertToListMap(dataList,
	                            this),
	                    R.layout.user_row, USER_ROW_COLUMNS,
	                    USER_ROW_VIEWS);
	            listAdapter.setViewBinder(userViewBinder);
	        	userListView.setAdapter(listAdapter);
	        	noUsersMessageContainer.setVisibility(View.GONE);
	        	userListView.setVisibility(View.VISIBLE);
	        	userListView.setOnItemClickListener(viewUserClickListener);
        	}
    	} else {
        	noUsersMessageContainer.setVisibility(View.VISIBLE);
        	userListView.setVisibility(View.GONE);
        	if (onActivityCreate) {
        		noUsersMessageContainer.setText("Loading users...");
        	} else {
        		noUsersMessageContainer.setText("Failed to load users");
        	}
        }

    }
    UserViewBinder userViewBinder = new UserViewBinder();
    
    private class UserViewBinder implements SimpleAdapter.ViewBinder {
        @Override
        public boolean setViewValue(final View view, final Object data, final String textRepresentation) {
            final int viewId = view.getId();
            if (viewId == R.id.user_name) {
                final User user = (User) data;
                final TextView iView = (TextView) view;
                iView.setTag(user);
                iView.setText(user.getName() + (" (" + user.getId() + ")"));
                return true;
            }
            return false;            
        }
    }

    private final AdapterView.OnItemClickListener viewUserClickListener = new AdapterView.OnItemClickListener() {
		@Override
		public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
				long arg3) {
			progressDialog = ProgressDialog.show(UserListActivity.this, null, "Loading user tour...");
			new StartMapTask(UserListActivity.this, (User)arg1.findViewById(R.id.user_name).getTag()).execute();
		}
    };
    
    private static class StartMapTask extends AsyncTask<Object, Void, StartMapTaskResult> {
    	final UserListActivity activity;
    	final User user;
    	
        public StartMapTask(UserListActivity activity, User user) {
            this.activity = activity;
            this.user = user;
        }
		@Override
		protected StartMapTaskResult doInBackground(Object... params) {
			try {
				JSONObject json = new JSONObject();
				json.put("userId", user.getId());
				json.put("peirod", 86400);
				JSONObject result = RequestUtility.executePostRequest("http://touring-engine.appspot.com/user/location/list", json);
				JSONArray array = result.getJSONArray("locations");
				int length = array.length();
				
				ArrayList<Location> locations = new ArrayList<Location>();
				for (int i = 0; i < length; ++i) {
					locations.add(Location.fromJSON(array.getJSONObject(i)));
				}
				return new StartMapTaskResult(locations);
			} catch (Exception ex) {
				return new StartMapTaskResult(ex);
			}
		}
		@Override
		protected void onPostExecute(StartMapTaskResult result) {
            if (activity.isFinishing() || activity.destroyed) {
                return;
            }
            try {
                final Exception exception = result.getException();
                if (exception != null) {
                	//showToast
                    Toast.makeText(activity,
                            "Failed to retrieve tour",
                            Toast.LENGTH_LONG).show();
                    return;
                } else {
                	if (result.getLocations().isEmpty()) {
	                    Toast.makeText(activity,
	                            "User has no points to show",
	                            Toast.LENGTH_LONG).show();
                	} else {
	                    Intent mapIntent = new Intent(activity, MapsActivity.class);
	                    mapIntent.putExtra("points", result.getLocations());
	                    activity.startActivity(mapIntent);
                	}
                }
            } finally {
            	if (activity.progressDialog != null) {
            		activity.progressDialog.dismiss();
            	}
                activity.updateView(false);
            }
		}
		
		
    }
    
    private static class StartMapTaskResult {
    	private Exception exception;
    	private ArrayList<Location> locations;
		public StartMapTaskResult(ArrayList<Location> locations) {
			this.locations = locations;
		}
    	
		public StartMapTaskResult(Exception exception) {
			this.exception = exception;
		}
    	
	    public Exception getException() {
				return exception;
			}
	
			public ArrayList<Location> getLocations() {
				return locations;
			}

	}

    private synchronized void loadData() {
        //
    }
    
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        if (mState != null) {
            outState.putSerializable(KEY_STATE, mState);
        }
    }

    public static class BrowseCommentsState implements java.io.Serializable {
        /**
         *
         */
        private static final long serialVersionUID = 9003134469982735164L;
        protected ArrayList<User> dataList;

    }

	@Override
	protected void onDestroy() {
		this.destroyed = true;
		super.onDestroy();
	}

	@Override
	public Loader<LoadUsersResult> onCreateLoader(int id, Bundle args) {
        // Now create and return a CursorLoader that will take care of
        // creating a Cursor for the data being displayed.
        return new DefaultAsyncTaskLoader<LoadUsersResult>(this) {
				@Override
				public LoadUsersResult load() {
		            int length = 0;
		            try {
		            	Thread.sleep(2000);
		            } catch (Exception e) {}
		            ArrayList<User> usersList = null;
		            JSONObject response = null;
		            try {
		                response = RequestUtility
		                        .executePostRequest(
		                                "http://touring-engine.appspot.com/user/list",
		                                new JSONObject());
		                JSONArray usersArray = response.getJSONArray("users");
		                length = usersArray.length();
		            	usersList = new ArrayList<User>();
		                for (int i = 0; i < length; ++i) {
		                	usersList.add(User.fromJSON(usersArray.getJSONObject(i)));
		                }

		                return new LoadUsersResult(usersList);
		            } catch (Exception ex) {
		                return new LoadUsersResult(ex);
		            }
				}
			};	
        }

	@Override
	public void onLoadFinished(Loader<LoadUsersResult> loader, LoadUsersResult result) {
        if (isFinishing() || destroyed) {
            return;
        }
        try {
            final Exception exception = result.getException();
            if (exception != null) {
            	//showToast
            	mState.dataList = result.getUsers();
                return;
            }
            mState.dataList = result.getUsers();
        } finally {
        	if (progressDialog != null) {
        		progressDialog.dismiss();
        	}
            updateView(false);
        }
	}

	@Override
	public void onLoaderReset(Loader<LoadUsersResult> loader) {
		mState.dataList = null;
	}
    
    
}
